import type { EventCallback, EventType, EventTypes } from '@/types';

/**
 * 事件总线类
 * 用于组件间的松耦合通信
 */
export class EventBus {
  private events: Map<string, EventCallback[]> = new Map();
  private debug: boolean = false;
  
  /**
   * 构造函数
   * @param debug 是否启用调试模式
   */
  constructor(debug: boolean = false) {
    this.debug = debug;
  }
  
  /**
   * 注册事件监听器
   * @param event 事件名称
   * @param callback 回调函数
   * @returns 用于取消监听的函数
   */
  on(event: string, callback: EventCallback): () => void {
    if (!this.events.has(event)) {
      this.events.set(event, []);
    }
    
    const callbacks = this.events.get(event)!;
    callbacks.push(callback);
    
    if (this.debug) {
      console.log(`[EventBus] Registered event: ${event}`);
    }
    
    // 返回取消监听的函数
    return () => {
      this.off(event, callback);
    };
  }
  
  /**
   * 注册一次性事件监听器
   * @param event 事件名称
   * @param callback 回调函数
   * @returns 用于取消监听的函数
   */
  once(event: string, callback: EventCallback): () => void {
    const unsubscribe = this.on(event, (payload) => {
      unsubscribe();
      callback(payload);
    });
    
    return unsubscribe;
  }
  
  /**
   * 发送事件
   * @param event 事件名称
   * @param payload 事件数据
   */
  emit(event: string, payload?: any): void {
    if (!this.events.has(event)) {
      if (this.debug) {
        console.log(`[EventBus] No listeners for event: ${event}`);
      }
      return;
    }
    
    if (this.debug) {
      console.log(`[EventBus] Emitting event: ${event}`, payload);
    }
    
    const callbacks = this.events.get(event)!;
    callbacks.forEach(callback => {
      try {
        callback(payload);
      } catch (error) {
        console.error(`[EventBus] Error in event handler for ${event}:`, error);
      }
    });
  }
  
  /**
   * 移除事件监听器
   * @param event 事件名称
   * @param callback 可选的回调函数，如果不提供则移除所有监听器
   */
  off(event: string, callback?: EventCallback): void {
    if (!this.events.has(event)) {
      return;
    }
    
    if (!callback) {
      this.events.delete(event);
      if (this.debug) {
        console.log(`[EventBus] Removed all listeners for event: ${event}`);
      }
      return;
    }
    
    const callbacks = this.events.get(event)!;
    const index = callbacks.indexOf(callback);
    if (index !== -1) {
      callbacks.splice(index, 1);
      if (this.debug) {
        console.log(`[EventBus] Removed a listener for event: ${event}`);
      }
    }
    
    if (callbacks.length === 0) {
      this.events.delete(event);
    }
  }
  
  /**
   * 移除所有事件监听器
   */
  clear(): void {
    this.events.clear();
    if (this.debug) {
      console.log(`[EventBus] Cleared all events`);
    }
  }
  
  /**
   * 获取特定事件的监听器数量
   * @param event 事件名称
   * @returns 监听器数量
   */
  listenerCount(event: string): number {
    if (!this.events.has(event)) {
      return 0;
    }
    return this.events.get(event)!.length;
  }
  
  /**
   * 获取所有已注册的事件名称
   * @returns 事件名称数组
   */
  eventNames(): string[] {
    return Array.from(this.events.keys());
  }
  
  /**
   * 设置调试模式
   * @param enabled 是否启用调试模式
   */
  setDebug(enabled: boolean): void {
    this.debug = enabled;
  }
}

// 创建全局事件总线实例
export const eventBus = new EventBus(process.env.NODE_ENV === 'development');

// 创建类型安全的事件发射器和监听器
export const emitEvent = <T extends keyof typeof EventTypes>(
  event: T,
  payload?: any
): void => {
  eventBus.emit(EventTypes[event], payload);
};

export const onEvent = <T extends keyof typeof EventTypes>(
  event: T,
  callback: EventCallback
): () => void => {
  return eventBus.on(EventTypes[event], callback);
};

export const onceEvent = <T extends keyof typeof EventTypes>(
  event: T,
  callback: EventCallback
): () => void => {
  return eventBus.once(EventTypes[event], callback);
};

export const offEvent = <T extends keyof typeof EventTypes>(
  event: T,
  callback?: EventCallback
): void => {
  eventBus.off(EventTypes[event], callback);
};